home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / QBASGDC1.ZIP / QBASGDC1.002 < prev   
Text File  |  1994-09-28  |  38KB  |  1,061 lines

  1. ╓───────────────╖
  2. ║ Week 2, Day 1 ║
  3. ╙───────────────╜
  4.  
  5. Our RPG will be simple, requiring you to navigate a maze and find the exit.
  6. To make things more interesting the maze will be populated with creatures that
  7. attack you.
  8. Defeat them and you will be rewarded in gold coins.
  9. Food, weapons and other useful items will be present in some rooms.
  10. Only one room has the exit but you must pay a toll of 100 gold pieces to use 
  11. it.
  12.  
  13. Lets begin by defining the maze and letting the player walk through it.
  14. (Entering "q" during play will stop the program.)
  15. Type (or edit) and RUN:
  16.  
  17. CLS
  18. row = 5
  19. column = 5
  20. moveErr$ = "You cannot move in that direction!"
  21.  
  22. LOCATE 14,1
  23. PRINT "Commands:   n - north"
  24. PRINT "            s - south"
  25. PRINT "            e - east"
  26. PRINT "            w - west"
  27. PRINT
  28. PRINT "            q - quit"
  29.  
  30. DO
  31.  LOCATE 1, 1
  32.  PRINT "Your position:"; row; column
  33.  LOCATE 8, 1
  34.  INPUT "What now"; reply$
  35.  LOCATE 10, 1
  36.  PRINT SPACE$(79)
  37.  
  38.  SELECT CASE reply$
  39.         CASE IS = "n"
  40.          IF row = 1 THEN
  41.           LOCATE 10, 1
  42.           PRINT moveErr$
  43.          ELSE
  44.           row = row - 1
  45.           LOCATE 10, 1
  46.           PRINT "You go north."
  47.          END IF
  48.         CASE IS = "s"
  49.          IF row = 10 THEN
  50.           LOCATE 10, 1
  51.           PRINT moveErr$
  52.          ELSE
  53.           row = row + 1
  54.           LOCATE 10, 1
  55.           PRINT "You go south."
  56.          END IF
  57.         CASE IS = "w"
  58.          IF column = 1 THEN
  59.           LOCATE 10, 1
  60.           PRINT moveErr$
  61.          ELSE
  62.           column = column - 1
  63.           LOCATE 10, 1
  64.           PRINT "You go west."
  65.          END IF
  66.         CASE IS = "e"
  67.          IF column = 10 THEN
  68.           LOCATE 10, 1
  69.           PRINT moveErr$
  70.          ELSE
  71.           column = column + 1
  72.           LOCATE 10, 1
  73.           PRINT "You go east."
  74.          END IF
  75.         CASE IS = "q"
  76.          LOCATE 10, 1
  77.          PRINT "Bye!"
  78.          END 
  79.  END SELECT
  80.  
  81. LOOP
  82.  
  83. You'll notice that the maze is 10 by 10 rooms in size.
  84. I you try to move outside its boundaries you are stopped and an error message
  85. appears (I stored it in variable "moveErr$" so there's less typing).
  86.  
  87. The command INPUT prompts the user for a value and stores it in a variable
  88. (reply$).
  89. As a bonus you can display some text at the same time ("What now").
  90.  
  91. SPACE$ is a function that provides spaces; SPACE$(2) gives you "  ".
  92. What the program does at that point is to overwrite any error messages that 
  93. resulted from the previous user input.  
  94.  
  95. "INT(RND * 10) + 1" gives a whole number ranging from 1 to 10.
  96. How does it work?
  97. INT gives the integer value of a variable, e.g. INT(1.9) gives 1.
  98. Because RND gives a value between 0 and 1, RND * 10 will give a value between
  99. 0 and 10.
  100. And because INT(0.99) = 0 and INT(9.99) = 9, it is necessary to add 1 to the 
  101. result.  
  102.  
  103. Now to add an exit to the maze:
  104.   
  105. CLS
  106. row = 5
  107. column = 5
  108. moveErr$ = "You cannot move in that direction!"
  109. exitRow = INT(RND * 10) + 1                       :REM  <─┬─ new
  110. exitColumn = INT(RND * 10) + 1                    :REM    │
  111. gold = 0                                          :REM   ─┘
  112.  
  113. LOCATE 14, 1
  114. PRINT "Commands:   n - north"
  115. PRINT "            s - south"
  116. PRINT "            e - east"
  117. PRINT "            w - west"
  118. PRINT "            x - use exit"                 :REM  <──- new
  119. PRINT
  120. PRINT "            q - quit"
  121.  
  122. DO
  123.  LOCATE 1, 1
  124.  PRINT "Your position:"; row; column
  125.                                                          :REM  <─┬─ new
  126.  IF ((row = exitRow) AND (column = exitColumn)) THEN
  127.   LOCATE 2, 1                                            :REM    │
  128.   PRINT "You are at the exit!"                           :REM    │
  129.  ELSE                                                    :REM    │
  130.   LOCATE 2, 1                                            :REM    │
  131.   PRINT SPACE$(79)                                       :REM    │
  132.  END IF                                                  :REM   ─┘
  133.  LOCATE 8, 1
  134.  INPUT "What now"; reply$
  135.  LOCATE 10, 1
  136.  PRINT SPACE$(79)
  137.  
  138.  SELECT CASE reply$
  139.         CASE IS = "n"
  140.          IF row = 1 THEN
  141.           LOCATE 10, 1
  142.           PRINT moveErr$
  143.          ELSE
  144.           row = row - 1
  145.           LOCATE 10, 1
  146.           PRINT "You go north."
  147.          END IF
  148.         CASE IS = "s"
  149.          IF row = 10 THEN
  150.           LOCATE 10, 1
  151.           PRINT moveErr$
  152.          ELSE
  153.           row = row + 1
  154.           LOCATE 10, 1
  155.           PRINT "You go south."
  156.          END IF
  157.         CASE IS = "w"
  158.          IF column = 1 THEN
  159.           LOCATE 10, 1
  160.           PRINT moveErr$
  161.          ELSE
  162.           column = column - 1
  163.           LOCATE 10, 1
  164.           PRINT "You go west."
  165.          END IF
  166.         CASE IS = "e"
  167.          IF column = 10 THEN
  168.           LOCATE 10, 1
  169.           PRINT moveErr$
  170.          ELSE
  171.           column = column + 1
  172.           LOCATE 10, 1
  173.           PRINT "You go east."
  174.          END IF
  175.         CASE IS = "x"                                           :REM  <─┬─ new
  176.          IF ((row = exitRow) AND (column = exitColumn)) THEN
  177.                                                                 :REM    │
  178.           IF gold < 100 THEN
  179.            LOCATE 10, 1                                         :REM    │
  180.            PRINT "You dont have enough gold!"                   :REM    │
  181.           ELSE                                                  :REM    │
  182.            LOCATE 10, 1                                         :REM    │
  183.            PRINT "You have escaped! Well done!"                 :REM    │
  184.            END                                                  :REM    │
  185.           END IF                                                :REM    │
  186.          END IF                                                 :REM   ─┘
  187.         CASE IS = "q"
  188.          LOCATE 10, 1
  189.          PRINT "Bye!"
  190.          END
  191.  END SELECT
  192.  
  193. LOOP
  194.  
  195. Thought you could escape?
  196. Maybe tomorrow when we add monsters and gold!
  197.  
  198. -------------------------------------------------------------------------------
  199. ╓───────────────╖
  200. ║ Week 2, Day 2 ║
  201. ╙───────────────╜
  202.  
  203. To make things interesting we'll use RND to scatter a variety of monsters
  204. throughout the maze.
  205. The amount of gold present in a room will depend on how difficult the monster
  206. is to beat.
  207. Type (or edit) and RUN:
  208.  
  209. CLS
  210. DIM monster(10, 10)                             :REM  <─┬- new
  211. FOR count1 = 1 TO 10                            :REM    │
  212.  FOR count2 = 1 TO 10                           :REM    │
  213.   monster(count1, count2) = INT(RND * 11)       :REM    │
  214.  NEXT count2                                    :REM    │
  215. NEXT count1                                     :REM   ─┘
  216.  
  217. row = 5
  218. column = 5
  219. moveErr$ = "You cannot move in that direction!"
  220. exitRow = INT(RND * 10) + 1
  221. exitColumn = INT(RND * 10) + 1
  222. gold = 0                 
  223.  
  224. DIM monster$(10)                            :REM  <─┬─ new
  225. RESTORE monsterData                         :REM    │
  226. FOR count = 1 TO 10                         :REM    │
  227.  READ monster$(count)                       :REM    │
  228. NEXT count                                  :REM   ─┘
  229.  
  230. LOCATE 14, 1
  231. PRINT "Commands:   n - north"
  232. PRINT "            s - south"
  233. PRINT "            e - east"
  234. PRINT "            w - west"
  235. PRINT "            x - use exit"
  236. PRINT
  237. PRINT "            q - quit"
  238.  
  239. DO
  240.  LOCATE 1, 1
  241.  PRINT "Your position:"; row; column
  242.  IF ((row = exitRow) AND (column = exitColumn)) THEN
  243.   LOCATE 2, 1
  244.   PRINT "You are at the exit!"
  245.  ELSE
  246.   LOCATE 2, 1
  247.   PRINT SPACE$(79)
  248.  END IF
  249.  LOCATE 3, 1                                         :REM  <─┬─ new
  250.  PRINT "Monster: ";                                  :REM    │
  251.  monsterType = monster(row, column)                  :REM    │
  252.  IF monsterType = 0 THEN
  253.   PRINT "nothing   "                                 :REM    │
  254.  ELSE                                                :REM    │
  255.   monsterName$ = MID$(monster$(monsterType), 1, 10)  :REM    │
  256.   PRINT monsterName$                                 :REM    │
  257.  END IF                                              :REM   ─┘
  258.  
  259.  LOCATE 8, 1
  260.  INPUT "What now"; reply$
  261.  LOCATE 10, 1
  262.  PRINT SPACE$(79)
  263.  
  264.  SELECT CASE reply$
  265.         CASE IS = "n"
  266.          IF row = 1 THEN
  267.           LOCATE 10, 1
  268.           PRINT moveErr$
  269.          ELSE
  270.           row = row - 1
  271.           LOCATE 10, 1
  272.           PRINT "You go north."
  273.          END IF
  274.         CASE IS = "s"
  275.          IF row = 10 THEN
  276.           LOCATE 10, 1
  277.           PRINT moveErr$
  278.          ELSE
  279.           row = row + 1
  280.           LOCATE 10, 1
  281.           PRINT "You go south."
  282.          END IF
  283.         CASE IS = "w"
  284.          IF column = 1 THEN
  285.           LOCATE 10, 1
  286.           PRINT moveErr$
  287.          ELSE
  288.           column = column - 1
  289.           LOCATE 10, 1
  290.           PRINT "You go west."
  291.          END IF
  292.         CASE IS = "e"
  293.          IF column = 10 THEN
  294.           LOCATE 10, 1
  295.           PRINT moveErr$
  296.          ELSE
  297.           column = column + 1
  298.           LOCATE 10, 1
  299.           PRINT "You go east."
  300.          END IF
  301.         CASE IS = "x"
  302.          IF ((row = exitRow) AND (column = exitColumn)) THEN
  303.           IF gold < 100 THEN
  304.            LOCATE 10, 1
  305.            PRINT "You dont have enough gold!"
  306.           ELSE
  307.            LOCATE 10, 1
  308.            PRINT "You have escaped! Well done!"
  309.            END
  310.           END IF
  311.          END IF
  312.         CASE IS = "q"
  313.          LOCATE 10, 1
  314.          PRINT "Bye!"
  315.          END
  316.  END SELECT
  317.  
  318. LOOP
  319.  
  320. monsterData:                      :REM  <─┬─ new
  321. DATA "blind bat "                 :REM    │
  322. DATA "rat       "                 :REM    │
  323. DATA "snake     "                 :REM    │
  324. DATA "goblin    "                 :REM    │
  325. DATA "troll     "                 :REM    │
  326. DATA "bear      "                 :REM    │
  327. DATA "lion      "                 :REM    │
  328. DATA "sabretooth"                 :REM    │
  329. DATA "elephant  "                 :REM    │
  330. DATA "dragon    "                 :REM   ─┘
  331.  
  332. I decided to allocate a number to each room to identify the type of monster in
  333. the room.
  334. To do this I needed 10 x 10 numbers.
  335. If we keep in mind that our player's location is stored as a row and a column
  336. value, its easy to see why I decided to to use a similar method of storing
  337. the monster values.
  338. Just by using row and column ( monster(row, column) ) you get the monster value
  339. at the player's location.
  340.  
  341. As you can see at the top of the program, I gave each location a monster value
  342. ranging from 0 to 10 (remember that INT(RND * 11) never gives 11).
  343. Why not 1 to 10?
  344. The 0 will serve as an indicator that there is no monster at that location.
  345.  
  346. What's RESTORE and READ?
  347. The READ command looks for DATA statements in your program and reads their
  348. values (e.g. the names of the monsters).
  349. It starts at the first DATA statement unless you use RESTORE to point it to
  350. a specific part of the program.
  351. RESTORE points to a LABEL (e.g. monsterData).
  352. You can put LABELS anywhere in your program, just remember to follow it with a
  353. colon.
  354.  
  355. Why READ the monster names when you can use: monster$(1) = "blind bat ",
  356. monster$(2) = "rat       ", etc?
  357. Its just easier to find the data if its grouped together.
  358. You can then use a FOR..NEXT loop to set the values rather than typing
  359. monster(x)="abcd" every time.
  360.  
  361. One last thing about READ: it remembers the position where it last read a value
  362. , so you have to use RESTORE if you want to read from the top again.     
  363.  
  364. Notice how I use the monster number (monsterType) to display its name from a
  365. monster$. 
  366. So if monsterType = 1 then monster$(monsterType) = "blind bat " will be
  367. displayed.
  368.  
  369. This should be enough reading for one day!
  370.  
  371. -------------------------------------------------------------------------------
  372. ╓───────────────╖
  373. ║ Week 2, Day 3 ║
  374. ╙───────────────╜
  375.  
  376. What good are monsters if they dont put up a fight?
  377. I'll rectify that if you type and RUN:
  378.  
  379. CLS
  380. DIM monster(10, 10)
  381. FOR count1 = 1 TO 10
  382.  FOR count2 = 1 TO 10
  383.   monster(count1, count2) = INT(RND * 11)
  384.  NEXT count2
  385. NEXT count1
  386.  
  387. row = 5
  388. column = 5
  389. moveErr$ = "You cannot move in that direction!"
  390. pressKey$ = "Press any key to continue."             :REM  <──- new
  391. exitRow = INT(RND * 10) + 1
  392. exitColumn = INT(RND * 10) + 1
  393. gold = 0
  394. health = 20                                          :REM  <─┬─ new
  395. weapon = 1                                           :REM   ─┘
  396.  
  397. DIM monster$(10)
  398. RESTORE monsterData
  399. FOR count = 1 TO 10
  400.  READ monster$(count)
  401. NEXT count
  402.  
  403. LOCATE 14, 1
  404. PRINT "Commands:   n - north"
  405. PRINT "            s - south"
  406. PRINT "            e - east"
  407. PRINT "            w - west"
  408. PRINT "            a - attack"             :REM  <──- new
  409. PRINT "            x - use exit"
  410. PRINT
  411. PRINT "            q - quit"
  412.  
  413. DO
  414.  LOCATE 1, 1
  415.  PRINT "Your position:"; row; column
  416.  LOCATE 1, 25                                           :REM  <─┬─ new
  417.  PRINT "Gold:"; gold; "  Health:"; health               :REM   ─┘
  418.   IF ((row = exitRow) AND (column = exitColumn)) THEN 
  419.   LOCATE 2, 1
  420.   PRINT "You are at the exit!"
  421.  ELSE
  422.   LOCATE 2, 1
  423.   PRINT SPACE$(79)
  424.  END IF
  425.  LOCATE 3, 1
  426.  PRINT "Monster: ";
  427.  monsterType = monster(row, column)
  428.  IF monsterType = 0 THEN
  429.   PRINT "nothing   "
  430.  ELSE
  431.   monsterName$ = MID$(monster$(monsterType), 1, 10)
  432.   PRINT monsterName$
  433.   monsterAttack = VAL(MID$(monster$(monsterType), 11, 1))     :REM  <─┬- new
  434.   monsterHealth = VAL(MID$(monster$(monsterType), 12, 1))     :REM    │
  435.   monsterGold = monsterType * INT(RND * 6)                    :REM   ─┘
  436.  END IF
  437.  
  438.  LOCATE 8, 1
  439.  INPUT "What now"; reply$
  440.  LOCATE 10, 1
  441.  PRINT SPACE$(79)
  442.  PRINT SPACE$(79)
  443.  PRINT SPACE$(79)
  444.   
  445.  SELECT CASE reply$
  446.         CASE IS = "n"
  447.          IF row = 1 THEN
  448.           LOCATE 10, 1
  449.           PRINT moveErr$
  450.          ELSE
  451.           row = row - 1
  452.           LOCATE 10, 1
  453.           PRINT "You go north."
  454.          END IF
  455.         CASE IS = "s"
  456.          IF row = 10 THEN
  457.           LOCATE 10, 1
  458.           PRINT moveErr$
  459.          ELSE
  460.           row = row + 1
  461.           LOCATE 10, 1
  462.           PRINT "You go south."
  463.          END IF
  464.         CASE IS = "w"
  465.          IF column = 1 THEN
  466.           LOCATE 10, 1
  467.           PRINT moveErr$
  468.          ELSE
  469.           column = column - 1
  470.           LOCATE 10, 1
  471.           PRINT "You go west."
  472.          END IF
  473.         CASE IS = "e"
  474.          IF column = 10 THEN
  475.           LOCATE 10, 1
  476.           PRINT moveErr$
  477.          ELSE
  478.           column = column + 1
  479.           LOCATE 10, 1
  480.           PRINT "You go east."
  481.          END IF
  482.         CASE IS = "x"
  483.          IF ((row = exitRow) AND (column = exitColumn)) THEN
  484.           IF gold < 100 THEN
  485.            LOCATE 10, 1
  486.            PRINT "You dont have enough gold!"
  487.           ELSE
  488.            LOCATE 10, 1
  489.            PRINT "You have escaped! Well done!"
  490.            END
  491.           END IF
  492.          END IF
  493.         CASE IS = "a"                                             :REM  <─┬ new
  494.          IF monsterType = 0 THEN
  495.           LOCATE 10, 1                                            :REM    │
  496.           PRINT "There's nothing to attack!"                      :REM    │
  497.          ELSE                                                     :REM    │
  498.           DO WHILE ((monsterHealth > 0) AND (health > 0))         :REM    │
  499.            LOCATE 10, 1                                           :REM    │
  500.            PRINT SPACE$(79)                                       :REM    │
  501.            PRINT SPACE$(79)                                       :REM    │
  502.            PRINT SPACE$(79)                                       :REM    │
  503.            LOCATE 10, 1                                           :REM    │
  504.            attack = weapon + INT(RND * 9)                         :REM    │
  505.            SELECT CASE attack                                     :REM    │
  506.                   CASE IS = monsterAttack                         :REM    │
  507.                    PRINT "No one wins this round."                :REM    │
  508.                   CASE IS > monsterAttack                         :REM    │
  509.                    PRINT "You deal the "; monsterName$; " a blow!":REM    │
  510.                    monsterHealth = monsterHealth - 1              :REM    │
  511.                   CASE IS < monsterAttack                         :REM    │
  512.                    PRINT "You have been wounded!"                 :REM    │
  513.                    health = health - 1                            :REM    │
  514.            END SELECT                                             :REM    │
  515.            PRINT pressKey$                                        :REM    │
  516.            SLEEP                                                  :REM    │
  517.           LOOP                                                    :REM    │
  518.           LOCATE 10, 1                                            :REM    │
  519.           IF health > 0 THEN
  520.            PRINT "You won the fight!"                             :REM    │
  521.            PRINT "You found "; monsterGold; " pieces of gold!"    :REM    │
  522.            gold = gold + monsterGold                              :REM    │
  523.            monsterType = 0                                        :REM    │
  524.            monster(row, column) = 0                               :REM    │
  525.            PRINT pressKey$                                        :REM    │
  526.            SLEEP                                                  :REM    │
  527.           ELSE                                                    :REM    │
  528.            PRINT "The "; monsterName$; " killed you!"             :REM    │
  529.            PRINT "Game over!"                                     :REM    │
  530.            END                                                    :REM    │
  531.           END IF                                                  :REM    │
  532.          END IF                                                   :REM   ─┘
  533.         CASE IS = "q"     
  534.          LOCATE 10, 1                                                
  535.          PRINT "Bye!"                                                
  536.          END                                                         
  537.  END SELECT                                                          
  538.  
  539. LOOP
  540.  
  541. monsterData:                    
  542. DATA "blind bat 21"                  :REM  <─┬─ changed
  543. DATA "rat       11"                  :REM    │
  544. DATA "snake     31"                  :REM    │
  545. DATA "goblin    23"                  :REM    │
  546. DATA "troll     44"                  :REM    │
  547. DATA "bear      55"                  :REM    │
  548. DATA "lion      54"                  :REM    │
  549. DATA "sabretooth65"                  :REM    │
  550. DATA "elephant  78"                  :REM    │
  551. DATA "dragon    98"                  :REM   ─┘
  552.  
  553. Starting from the top:
  554. The variable "health" starts of at 20 but 1 gets subtracted from it each time a
  555. monster hits you.
  556. If it reaches 0 you've had it.
  557. The variable "weapon" gets added to your attack score: weapon + INT(RND * 9).
  558. So the attack score will range from 1 to 9. (INT(RND * 9) gives 0 to 8)
  559.  
  560. MonsterAttack: A monster's attack score is stored as the second last character
  561.                in a monster$.
  562. VAL takes a string and converts it to a decimal value, so VAL("10") gives 10.
  563. Trying something like VAL("ABC") will cause a runtime error.
  564.  
  565. MonsterHealth: The last character READ into a monster$ is the monster's health.
  566.                Each time you wound it, it loses a point of health and dies when
  567.                it loses all its points.
  568.  
  569. MonsterGold: I chose to add a random factor to the amount of gold found, but by
  570.              multiplying with monsterAttack you should still find more gold 
  571.              after defeating tougher monsters.
  572.  
  573. Notice that fighting takes place and continues until one side runs out of 
  574. health.
  575. So when this loop terminates we know that if your health > 0 then the monster's
  576. health must have run out.
  577. If the monster loses then monsterType is set to 0 so that you cannot fight
  578. it again.
  579. Monsters(row, column) = 0 changes the location's monster to "nothing", so when
  580. you enter this location again there will be no monsters.
  581.  
  582. Can you remember that the SLEEP command is used to pause the program for a
  583. number of seconds?
  584. SLEEP on its own waits indefinitely or until a key is pressed.
  585. I've used it to wait for a keypress.
  586. You can use   DO: LOOP UNTIL INKEY$ <> ""   instead of SLEEP.
  587.  
  588. Thats all for now!
  589.  
  590. -------------------------------------------------------------------------------
  591. ╓───────────────╖
  592. ║ Week 2, Day 4 ║
  593. ╙───────────────╜
  594.  
  595. Lets scatter some useful items like food and weapons throughout the maze.
  596. To balance things we'll add a few traps..
  597.  
  598. CLS
  599. RANDOMIZE TIMER                                 :REM  <─── new
  600. DIM monster(10, 10)
  601. FOR count1 = 1 TO 10
  602.  FOR count2 = 1 TO 10
  603.   monster(count1, count2) = INT(RND * 11)
  604.  NEXT count2
  605. NEXT count1
  606.  
  607. DIM item(10, 10)                                :REM  <─┬─ new
  608. FOR count1 = 1 TO 10                            :REM    │
  609.  FOR count2 = 1 TO 10                           :REM    │
  610.   IF RND < .2 THEN                              :REM    │
  611.    item(count1, count2) = INT(RND * 9) + 1      :REM    │
  612.   ELSE                                          :REM    │
  613.    item(count1, count2) = 0                     :REM    │
  614.   END IF                                        :REM    │
  615.  NEXT count2                                    :REM    │
  616. NEXT count1                                     :REM   ─┘
  617.  
  618. row = 5
  619. column = 5
  620. moveErr$ = "You cannot move in that direction!"
  621. pressKey$ = "Press any key to continue."
  622. exitRow = INT(RND * 10) + 1
  623. exitColumn = INT(RND * 10) + 1
  624. gold = 0
  625. health = 20
  626. weapon = 1
  627.  
  628. DIM monster$(10)
  629. RESTORE monsterData
  630. FOR count = 1 TO 10
  631.  READ monster$(count)
  632. NEXT count
  633.  
  634. DIM item$(9)                                    :REM  <─┬─ new
  635. RESTORE itemData                                :REM    │
  636. FOR count = 1 TO 9                              :REM    │
  637.  READ item$(count)                              :REM    │
  638. NEXT count                                      :REM   ─┘
  639.  
  640. LOCATE 14, 1
  641. PRINT "Commands:   n - north"
  642. PRINT "            s - south"
  643. PRINT "            e - east"
  644. PRINT "            w - west"
  645. PRINT "            a - attack"
  646. PRINT "            t - take item"               :REM  <─── new
  647. PRINT "            x - use exit"
  648. PRINT
  649. PRINT "            q - quit"
  650.  
  651. LOCATE 14, 40                                           :REM  <─┬─ new
  652. PRINT CHR$(201); STRING$(10, CHR$(205)); CHR$(187)      :REM    │
  653. LOCATE 15, 40                                           :REM    │
  654. PRINT CHR$(186); SPACE$(10); CHR$(186)                  :REM    │
  655. LOCATE 16, 40                                           :REM    │
  656. PRINT CHR$(200); STRING$(10, CHR$(205)); CHR$(188)      :REM    │
  657. LOCATE 17, 44                                           :REM    │
  658. PRINT "ITEM"                                            :REM   ─┘
  659.  
  660. DO
  661.  LOCATE 1, 1
  662.  PRINT "Your position:"; row; column
  663.  LOCATE 1, 25
  664.  PRINT "Gold:"; gold; "  Health:"; health; "  Weapon:"; weapon  :REM <──changed
  665.   IF ((row = exitRow) AND (column = exitColumn)) THEN
  666.   LOCATE 2, 1
  667.   PRINT "You are at the exit!"
  668.  ELSE
  669.   LOCATE 2, 1
  670.   PRINT SPACE$(79)
  671.  END IF
  672.  LOCATE 3, 1
  673.  PRINT "Monster: ";
  674.  monsterType = monster(row, column)
  675.  IF monsterType = 0 THEN
  676.   PRINT "nothing   "
  677.  ELSE
  678.   monsterName$ = MID$(monster$(monsterType), 1, 10)
  679.   PRINT monsterName$
  680.   monsterAttack = VAL(MID$(monster$(monsterType), 11, 1))
  681.   MonsterHealth = VAL(MID$(monster$(monsterType), 12, 1))
  682.   MonsterGold = monsterType * INT(RND * 6)
  683.  END IF
  684.  
  685.  itemType (or edit) = item(row, column)                           :REM  <─┬─ new
  686.  IF itemType (or edit) = 0 THEN                                   :REM    │
  687.   LOCATE 15, 41                                         :REM    │
  688.   PRINT "nothing   "                                    :REM    │
  689.  ELSE                                                   :REM    │
  690.   itemName$ = LEFT$(item$(itemType (or edit)), 10)                :REM    │
  691.   itemClass$ = MID$(item$(itemType (or edit)), 11, 1)             :REM    │
  692.   itemValue = VAL(RIGHT$(item$(itemType (or edit)), 1))           :REM    │
  693.   LOCATE 15, 41                                         :REM    │
  694.   PRINT itemName$                                       :REM    │
  695.   IF itemClass$ = "T" THEN                              :REM    │
  696.    LOCATE 10, 1                                         :REM    │
  697.    PRINT "The "; RTRIM$(itemName$); " damages you for "; itemValue; " points!"
  698.    health = health - itemValue                          :REM    │
  699.    item(row, column) = 0                                :REM    │
  700.    itemType (or edit) = 0                                         :REM    │
  701.    IF health <= 0 THEN                                  :REM    │
  702.     PRINT "You die!"                                    :REM    │
  703.     PRINT "Game over!"                                  :REM    │
  704.     END                                                 :REM    │
  705.    END IF                                               :REM    │
  706.   END IF                                                :REM    │
  707.  END IF                                                 :REM   ─┘
  708.  
  709.  LOCATE 8, 1
  710.  INPUT "What now"; reply$
  711.  LOCATE 10, 1
  712.  PRINT SPACE$(79)
  713.  PRINT SPACE$(79)
  714.  PRINT SPACE$(79)
  715.   
  716.  SELECT CASE reply$
  717.         CASE IS = "n"
  718.          IF row = 1 THEN
  719.           LOCATE 10, 1
  720.           PRINT moveErr$
  721.          ELSE
  722.           row = row - 1
  723.           LOCATE 10, 1
  724.           PRINT "You go north."
  725.          END IF
  726.         CASE IS = "s"
  727.          IF row = 10 THEN
  728.           LOCATE 10, 1
  729.           PRINT moveErr$
  730.          ELSE
  731.           row = row + 1
  732.           LOCATE 10, 1
  733.           PRINT "You go south."
  734.          END IF
  735.         CASE IS = "w"
  736.          IF column = 1 THEN
  737.           LOCATE 10, 1
  738.           PRINT moveErr$
  739.          ELSE
  740.           column = column - 1
  741.           LOCATE 10, 1
  742.           PRINT "You go west."
  743.          END IF
  744.         CASE IS = "e"
  745.          IF column = 10 THEN
  746.           LOCATE 10, 1
  747.           PRINT moveErr$
  748.          ELSE
  749.           column = column + 1
  750.           LOCATE 10, 1
  751.           PRINT "You go east."
  752.          END IF
  753.         CASE IS = "x"
  754.          IF ((row = exitRow) AND (column = exitColumn)) THEN
  755.           IF gold < 100 THEN
  756.            LOCATE 10, 1
  757.            PRINT "You dont have enough gold!"
  758.           ELSE
  759.            LOCATE 10, 1
  760.            PRINT "You have escaped! Well done!"
  761.            END
  762.           END IF
  763.          END IF
  764.         CASE IS = "a"
  765.          IF monsterType = 0 THEN
  766.           LOCATE 10, 1
  767.           PRINT "There's nothing to attack!"
  768.          ELSE
  769.           DO WHILE ((MonsterHealth > 0) AND (health > 0))
  770.            LOCATE 10, 1
  771.            PRINT SPACE$(79)
  772.            PRINT SPACE$(79)
  773.            PRINT SPACE$(79)
  774.            LOCATE 10, 1
  775.            attack = weapon + INT(RND * 9)
  776.            SELECT CASE attack
  777.                   CASE IS = monsterAttack
  778.                    PRINT "No one wins this round."
  779.                   CASE IS > monsterAttack
  780.                                                               :REM  <── changed
  781.                    PRINT "You deal the "; RTRIM$(monsterName$); " a blow!"
  782.                                                               :REM   ─────┘
  783.                    MonsterHealth = MonsterHealth - 1
  784.                   CASE IS < monsterAttack
  785.                    PRINT "You have been wounded!"
  786.                    health = health - 1
  787.            END SELECT
  788.            PRINT pressKey$
  789.            SLEEP
  790.           LOOP
  791.           LOCATE 10, 1
  792.           IF health > 0 THEN
  793.            PRINT "You won the fight!"; SPACE$(20)
  794.            PRINT "You found "; MonsterGold; " pieces of gold!"
  795.            gold = gold + MonsterGold
  796.            monsterType = 0
  797.            monster(row, column) = 0
  798.            PRINT pressKey$
  799.            SLEEP
  800.           ELSE
  801.                                                               :REM  <── changed
  802.            PRINT "The "; RTRIM$(monsterName$); " killed you!"; SPACE$(20)
  803.                                                               :REM   ─────┘
  804.            PRINT "Game over!"; SPACE$(20)
  805.            END
  806.           END IF
  807.          END IF
  808.         CASE IS = "t"                                               :REM <─┐new
  809.          IF itemType (or edit) = 0 THEN                                       :REM   │
  810.           LOCATE 10, 1                                              :REM   │
  811.           PRINT "Nothing to take!"                                  :REM   │
  812.           PRINT pressKey$                                           :REM   │
  813.           SLEEP                                                     :REM   │
  814.          ELSE                                                       :REM   │
  815.           SELECT CASE itemClass$                                    :REM   │
  816.                 CASE IS = "F"                                       :REM   │
  817.                  LOCATE 10, 1                                       :REM   │
  818.                  PRINT "You eat the "; RTRIM$(itemName$); "."       :REM   │
  819.                  IF health = 20 THEN                                :REM   │
  820.                   PRINT "You had no wounds, so the food is wasted." :REM   │
  821.                  ELSE                                               :REM   │
  822.                   health = health + itemValue                       :REM   │
  823.                   PRINT "You gain "; itemValue; " health points."   :REM   │
  824.                  END IF                                             :REM   │
  825.                 CASE IS = "W"                                       :REM   │
  826.                  LOCATE 10, 1                                       :REM   │
  827.                  IF weapon >= itemValue THEN                        :REM   │
  828.                   PRINT "You have a similar or better weapon."      :REM   │
  829.                  ELSE                                               :REM   │
  830.                   PRINT "You pick up a "; RTRIM$(itemName$); " !"   :REM   │
  831.                   weapon = itemValue                                :REM   │
  832.                   PRINT "Your weapon rating is now "; weapon; "."   :REM   │
  833.                  END IF                                             :REM   │
  834.           END SELECT                                                :REM   │
  835.           PRINT pressKey$                                           :REM   │
  836.           SLEEP                                                     :REM   │
  837.           item(row, column) = 0                                     :REM   │
  838.           itemType (or edit) = 0                                              :REM   │
  839.          END IF                                                     :REM  ─┘
  840.         CASE IS = "q"
  841.          LOCATE 10, 1
  842.          PRINT "Bye!"
  843.          END
  844.  END SELECT
  845.  
  846. LOOP
  847.  
  848. monsterData:                 
  849. DATA "blind bat 21"               
  850. DATA "rat       11"               
  851. DATA "snake     31"               
  852. DATA "goblin    23"               
  853. DATA "troll     44"               
  854. DATA "bear      55"               
  855. DATA "lion      54"               
  856. DATA "sabretooth65"               
  857. DATA "elephant  78"               
  858. DATA "dragon    98"               
  859.  
  860. itemData:                               :REM  <─┬─ new
  861. DATA "apple     F1"                     :REM    │
  862. DATA "bread     F2"                     :REM    │
  863. DATA "chicken   F3"                     :REM    │
  864. DATA "dagger    W2"                     :REM    │
  865. DATA "sword     W3"                     :REM    │
  866. DATA "halberd   W4"                     :REM    │
  867. DATA "smoke     T1"                     :REM    │
  868. DATA "noose trapT2"                     :REM    │
  869. DATA "pit trap  T3"                     :REM   ─┘
  870.  
  871. Starting from the top:
  872. You have probably noticed that, although RND gives random effects, you keep
  873. getting the same set of random values!
  874. This is because the computer uses a base value (called a "seed") to start
  875. calculating RND.
  876. RANDOMIZE sets the "seed" to a new value so the RNDs will be different.
  877. The value of TIMER is the amount of seconds since midnight.
  878. Because this value keeps changing we use it as a "seed" in the expression
  879. RANDOMIZE TIMER.
  880.  
  881. Items are addressed by using the array item(10, 10), allowing for one item
  882. per room in the maze.
  883. There's only a 20% chance of a room having an item (RND < .2) and then the
  884. item is identified by a number ranging from 1 to 9.
  885. More data on the 9 different item types is READ into item$.
  886.  
  887. CHR$ is used to convert an ASCII value into a character.
  888. So instead of doing PRINT "A", we can use PRINT CHR$(65), 65 being its ASCII
  889. value.
  890. By using CHR$ we can access some nice characters for graphical purposes.
  891. To view these characters in QBasic: Press SHIFT-F1.  Choose the "Contents" box,
  892. then choose the "ASCII character codes" box.
  893. The character with ASCII value 2 would make a nice PACMAN.
  894.  
  895. Each "item" has a name, class and value.
  896. The class shows whether its food ("F"), a weapon ("W"), or a trap("T").
  897. The value is used differently for each class:
  898. class:  food           Value:  number of health points gained by player
  899.         weapon                 new "weapon" value for player
  900.         trap                   number of health points player will lose
  901.  
  902. LEFT$(a$, 10) is the same as MID$(a$, 1, 10), in other words it just starts
  903. at the first position in the string.
  904. RIGHT$("ABCDE", 3) gives "CDE", in other words it takes the rightmost 3
  905. characters.
  906. You can use MID$ instead of LEFT$ and RIGHT$, but its possible to save time by
  907. using them.
  908.  
  909. The "trap" item immediately damages the player upon entering the room.
  910. The trap is then disabled by removing it from the array (item(row, column) = 0)
  911.  
  912. RTRIM$("ABC  ") gives "ABC", in other words it removes the spaces on the right.
  913. LTRIM$ work in the same way, but removes spaces from the left.
  914.  
  915. I added some interesting checks for when a player takes an item.
  916. If he takes food and he has no wounds (health = 20), the food goes to waste.
  917. If he tries to take a weapon thats rated worse or the same as his present
  918. weapon, he is stopped.
  919.  
  920. This concludes our RPG.
  921. Tomorrow I'll illustrate a few commands for generating graphics.
  922.  
  923. -------------------------------------------------------------------------------
  924. ╓───────────────╖
  925. ║ Week 2, Day 5 ║
  926. ╙───────────────╜
  927.  
  928. I'll demonstrate manipulation of a simple graphic by putting the screen in
  929. graphics mode (its usually in text mode), drawing the graphic, grabbing it
  930. from the screen and storing it in an array, displaying it again from the array
  931. while shifting its position from the left to the right of the screen.
  932. (I have a long breath!)
  933. Here goes:
  934.  
  935. REM SCREEN mode number
  936. REM        1 = CGA 320x200, 4 colors Graphics mode
  937. SCREEN 1
  938.  
  939. REM COLOR palette number,                      background color
  940. REM       0 -> black, green, red,     brown    0 to 15
  941. REM       1 -> black, cyan,  magenta, white
  942. REM      color = 0     1      2        3
  943. COLOR 0, 1
  944.  
  945. xDim = 16: REM The width of the image in pixels
  946. yDim = 16: REM The height of the imgae in pixels
  947.  
  948. REM Use this formula for calculating the size of the array needed to store
  949. REM the image.  The size is measured in bytes.
  950. size = 4 + INT(((xDim + 1) * 2 + 7) / 8) * (yDim + 1)
  951.  
  952. DIM pic(size / 2) AS INTEGER: REM An INTEGER is two bytes in size
  953.  
  954. REM Draw a block 14x14 pixels in size and fill it.
  955. REM LINE (startX, startY)-(endX, endY), color, BF=block fill
  956. REM The entire screen starts at (0, 0) and ends at (319, 199)
  957. LINE (1, 1)-(14, 14), 1, BF
  958.  
  959. REM Get a 16x16 image from the screen and store it in the array pic.
  960. GET (0, 0)-(15, 15), pic
  961.  
  962. CLS
  963.  
  964. FOR count = 0 TO 320 - 16
  965.  REM Put the image on the screen. PSET makes it overwrite the previous image.
  966.  PUT (count, 90), pic, PSET
  967.  REM Slow down the computer.  Make the value bigger if its still too fast.
  968.  FOR nothing = 1 TO 100
  969.  NEXT nothing
  970. NEXT count
  971.  
  972. END
  973.  
  974. The REMs explain nearly everything.
  975. Experiment with colors by choosing one of the two sets (four colors in each
  976. set) by modifying the COLOR statement.
  977. Then choose between the four available colors by modifying the LINE statement.
  978.  
  979. Why did I draw a 14x14 image but stored it as a 16x16 image?
  980. That way the stored image is surrounded by a "frame" of black dots.
  981. When moving the image around, the black "frame" deletes the previous (old)
  982. image.
  983. So I'm displaying the image in its new position and deleting the old image at
  984. the same time!
  985.  
  986. You could make more interesting images by using the PSET command which places
  987. dots on the screen.
  988. Type (or edit) and RUN:
  989.  
  990. SCREEN 1
  991. COLOR 0, 1
  992.  
  993. xDim = 8
  994. yDim = 8
  995.  
  996. size = 4 + INT(((xDim + 1) * 2 + 7) / 8) * (yDim + 1)
  997.  
  998. DIM pic(size / 2) AS INTEGER
  999.  
  1000. RESTORE pacmanPic
  1001. FOR row = 1 TO yDim
  1002.  FOR column = 1 TO xDim
  1003.   READ picData
  1004.   PSET (column, row), picData
  1005.  NEXT column
  1006. NEXT row
  1007.  
  1008. GET (0, 0)-(xDim - 1, yDim - 1), pic
  1009.  
  1010. CLS
  1011.  
  1012. FOR count = 0 TO 320 - 16
  1013.  PUT (count, 90), pic, PSET
  1014.  FOR nothing = 1 TO 100
  1015.  NEXT nothing
  1016. NEXT count
  1017.  
  1018. END
  1019.  
  1020. pacmanPic:
  1021. DATA 0,0,0,0,0,0,0,0
  1022. DATA 0,0,1,1,1,1,0,0
  1023. DATA 0,1,1,1,2,1,1,0
  1024. DATA 0,1,1,0,0,0,0,0
  1025. DATA 0,1,1,0,0,0,0,0
  1026. DATA 0,1,1,1,1,1,1,0
  1027. DATA 0,0,1,1,1,1,0,0
  1028. DATA 0,0,0,0,0,0,0,0
  1029.  
  1030. Storing the pixels as DATA beats doing every one with the PSET command!
  1031. Try changing the picture DATA using the values 0 to 3.
  1032.  
  1033. Just by changing yDim and xDim and the DATA you can now design and display a
  1034. bigger or smaller picture.
  1035.  
  1036. -------------------------------------------------------------------------------
  1037. Thats all folks!
  1038. ================
  1039. Hope you enjoyed the course - I can honestly say that I enjoyed writing it.
  1040.  
  1041. If you have any comments or questions you can E-mail me at my Internet address:
  1042. ┌───────────────────────┐
  1043. │ avw@mickey.iaccess.za │
  1044. └───────────────────────┘
  1045. or you can reach me by snail-mail:
  1046. ┌───────────────────┐
  1047. │ A. van Wyk        │
  1048. │ 105 Sidvale Court │
  1049. │ Parow             │
  1050. │ 7500              │
  1051. │ Western Cape      │
  1052. │ South Africa      │
  1053. └───────────────────┘
  1054.  
  1055. If you have found the course useful and would like to see further modules, just
  1056. let me know!
  1057. Time allowing and if there is sufficient interest, I will expand on the course.
  1058.  
  1059. Cheers for now,
  1060. Andre
  1061.